﻿//begin
//
//
package effects.fractal
{
	//
	//
	//
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BitmapDataChannel;
	import flash.display.StageScaleMode;
	import flash.utils.*;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.geom.Point;
	import flash.geom.Matrix;
	import evo.engine.AbstractDemoEffect;	

	public class JuliaEffect extends AbstractDemoEffect
	{
		private var mbBMP:BitmapData;
		private var moveTimer:Timer;
		//
		private var iterations:int = 256;

		private var WTH:int;
		private var HTH:int;
		//
		
//		private var pixCenter:int=127*257;
		
		private var pix:Array;
		private var hw:Array;
		private var sqrt:Array;
		
		private var re:int=4;
		private var im:int=2;
		private var ingvar:Number=0;
		
	/*	private var redp:Array;
		private var greenp:Array;
		private var bluep:Array;
		private var alphap:Array;*/
		
		private var palette:Array;
		
		private var testibmp:BitmapData;
		private var testibmp2:BitmapData;

		private var stack:Array;
		private var scaleMtx:Matrix;
		private var invertMtx:Matrix;
		
		//
		//
		//
		public override function init(params:Object=null):void
		{
			super.init(params);
			WTH = 256;
			HTH = 128;
			mbBMP = new BitmapData( WTH , HTH , false , 0x000000 );
			stack=new Array();
			pix=new Array(256*256);
			
			palette=new Array(256);

			var i:int= 0;
			var f:Number;
			var a:int;
			for(i=0; i < 256; i++) 
			{
				f=i/255.0;
				a=(f*2.8 + .2*(f*f))*255;
				if(a>255)a=255;
				palette[i]=(a<<16)+(a<<8)+a;
			}
			
			testibmp=new BitmapData(WTH, HTH, false, 0);
			testibmp2=new BitmapData(WTH, HTH, false, 0);
			
			sqrt=new Array(256);
			hw=new Array(256);
			
			for(i=0; i < 128; i++) {
				hw[i]=hw[255-i]=int(128*Math.sin(Math.acos ((128-i)/128.0)));
				sqrt[127-i]=sqrt[128+i]=i*i
			}
		}
		
		public override function set output(buffer:BitmapData):void
		{
			super.output = buffer;

			scaleMtx = new Matrix();
			scaleMtx.scale(buffer.width/(WTH*2), buffer.height/(HTH*2));
			scaleMtx.translate(buffer.width/4,0);
			invertMtx = scaleMtx.clone();
			invertMtx.translate(-buffer.width/2, -buffer.height/2);
			invertMtx.scale(-1, -1);
			invertMtx.translate(buffer.width/2, buffer.height/2);
		}
		
		//
		//
		//
		private var oldtime:int=0;
		private var gotovar:Number=0;
		
		public override function play(dt:Number):void
		{	
			ingvar += dt/30;
			re=2000*Math.cos(0.037*(ingvar+.132)); //int(1.2 * 2048*Math.cos(0.11*ingvar));
			im=2000*Math.cos(0.064*(ingvar+.4139)); //int(1.5 * 1024*Math.sin(0.11*ingvar + 0.4711));
			testibmp.draw(testibmp2);
			mbBMP.lock();
			mbBMP.draw(testibmp2);
			for(var y:int=0; y < 100; y++) {
				var t:int=hw[y+127]+1;
				for(var x:int = -hw[y+127]; x < t; x++) {
					calcPix(x,y);
				}
			}
			mbBMP.unlock();

			//mbBMP.paletteMap(testibmp, fullrect, trpoint, null, null, palette);
			//mbBMP.draw(testibmp);

			output.draw(mbBMP, scaleMtx);
			output.draw(mbBMP, invertMtx);	
		}

		//
		//
		//

		private function calcPix(ix:int, iy:int):void {
			
			var x:int=ix, y:int=iy;
			var nx:int, ny:int;
			var iter:int;
			var spos:int=0;
			var c:int;

			while(true) {
				if(y>0) {
					y=-y;
					x=-x;
				}
				iter=testibmp.getPixel(128+x, 128+y);
				if(iter != 0) break;
				
				ny = (x*y + im) >> 5;
				if( ny < 128 && ny > -128) {
					nx = (x*x - y*y + re) >> 6;
					var tmp:Number=hw[ny+127];
					if(nx <= tmp && nx >= -tmp) {
						stack[spos]=(y+128) << 8 | (x+128);
						spos+=1
						x=nx;
						y=ny;
						if(spos < iterations) continue;
						iter=iterations;
					}
				} 
				break;
			}

			if(spos==0) return;
			var pos:int;
			var i:int=0;
			//for(i=0; i < spos; i++) {
			for each(pos in stack) {
				//pos=stack[i];
				
				var it:int=iter+((spos-1)-i)+1;
				
				if(it > iterations) it=iterations;
				
				var cl:int=palette[(int(it)&0x3F)<<2];
				//trace("Setting pixel at:"+(pos&0xFF)+":"+ (pos>>8)+" c1:"+it+" c2:"+cl.toString(16));
				testibmp.setPixel(pos&0xFF, pos>>8,it);
				mbBMP.setPixel(pos&0xFF, pos>>8, cl);

				if(++i >= spos) break;
			}
		}
	}

	//
	//
	//
}
//
//
//end